/*
 * Copyright 2012 Objectos, Fábrica de Software LTDA.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package br.com.objectos.way.cnab;

import static br.com.objectos.way.cnab.remessa.Caixa.ALTA;
import static br.com.objectos.way.cnab.remessa.EnderecamentoDebitoAutomatico.CADASTRO_CONSTANTE;

import org.joda.time.LocalDate;

import br.com.objectos.way.base.br.CadastroRFB;
import br.com.objectos.way.base.br.Cep;
import br.com.objectos.way.cnab.AbstractRemessaSpec.ColBuilder;
import br.com.objectos.way.cnab.paulista.TipoDeIncricaoDoSacado;
import br.com.objectos.way.cnab.remessa.Comando;
import br.com.objectos.way.cnab.remessa.EnderecamentoDebitoAutomatico;
import br.com.objectos.way.cnab.remessa.EspecieDeTitulo;

/**
 * @author marcos.piazzolla@objectos.com.br (Marcos Piazzolla)
 */
class PaulistaLoteRemessaSpec
  extends AbstractRemessaSpec<PaulistaLoteRemessa> implements PaulistaLoteRemessa {
  private final CnabKey<PaulistaLoteRemessa, String> idDoRegistro;
  private final CnabKey<PaulistaLoteRemessa, String> debitoAutomaticoCC;
  private final CnabKey<PaulistaLoteRemessa, Integer> coObrigacao;
  private final CnabKey<PaulistaLoteRemessa, Integer> caracteristicaEspecial;
  private final CnabKey<PaulistaLoteRemessa, Integer> modalidadeDaOperacao;
  private final CnabKey<PaulistaLoteRemessa, Integer> naturezaDaOperacao;
  private final CnabKey<PaulistaLoteRemessa, Integer> origemDoRecurso;
  private final CnabKey<PaulistaLoteRemessa, String> classeRiscoDaOperacao;
  private final CnabKey<PaulistaLoteRemessa, String> zeros;
  private final CnabKey<PaulistaLoteRemessa, String> numeroDeControleDoParticipante;
  private final CnabKey<PaulistaLoteRemessa, Integer> numeroDoBanco;
  private final CnabKey<PaulistaLoteRemessa, String> zeros2;
  private final CnabKey<PaulistaLoteRemessa, String> idTituloNoBanco;
  private final CnabKey<PaulistaLoteRemessa,String> nossoNumero;
  private final CnabKey<PaulistaLoteRemessa, Double> valorPago;
  private final CnabKey<PaulistaLoteRemessa, String> condicaoParaEmissaoDaPapeletaDeCobranca;
  private final CnabKey<PaulistaLoteRemessa, String> idSeEmitePapeletaParaDebitoAutomatico;
  private final CnabKey<PaulistaLoteRemessa, LocalDate> dataDeLiquidacao;
  private final CnabKey<PaulistaLoteRemessa, String> idOperacaoDoBanco;
  private final CnabKey<PaulistaLoteRemessa, String> indicadorRateioCredito;
  private final CnabKey<PaulistaLoteRemessa, String> enderecamentoParaAvisoDoDebitoAutomaticoEmCC;
  private final CnabKey<PaulistaLoteRemessa, String> branco;
  private final CnabKey<PaulistaLoteRemessa, Integer> idOcorrencia;
  private final CnabKey<PaulistaLoteRemessa, String> numeroDoDocumento;
  private final CnabKey<PaulistaLoteRemessa, LocalDate> dataDeVencimentoDoTitulo;
  private final CnabKey<PaulistaLoteRemessa, Double> valorFaceDoTitulo;
  private final CnabKey<PaulistaLoteRemessa, Integer> bancoEncarregadoDaCobranca;
  private final CnabKey<PaulistaLoteRemessa, String> agenciaDepositaria;
  private final CnabKey<PaulistaLoteRemessa, Integer> especieDeTitulo;
  private final CnabKey<PaulistaLoteRemessa, String> identificacao;
  private final CnabKey<PaulistaLoteRemessa, LocalDate> dataDeEmissaoDoTitulo;
  private final CnabKey<PaulistaLoteRemessa, String> primeiraInstrucao;
  private final CnabKey<PaulistaLoteRemessa, String> segundaInstrucao;
  private final CnabKey<PaulistaLoteRemessa, String> zeros3;
  private final CnabKey<PaulistaLoteRemessa, String> numeroDeTermoDeCessao;
  private final CnabKey<PaulistaLoteRemessa, Double> valorPresenteDaParcela;
  private final CnabKey<PaulistaLoteRemessa, Double> valorDoAbatimento;
  private final CnabKey<PaulistaLoteRemessa, TipoDeIncricaoDoSacado> identificacaoDoTipoDeInscricaoDoSacado;
  private final CnabKey<PaulistaLoteRemessa,CadastroRFB> numeroInscricaoDoSacado;
  private final CnabKey<PaulistaLoteRemessa, String> nomeDoSacado;
  private final CnabKey<PaulistaLoteRemessa,String> enderecoCompletoDoSacado;
  private final CnabKey<PaulistaLoteRemessa, String> numeroDeNotaFiscalDaDuplicata;
  private final CnabKey<PaulistaLoteRemessa, String> numeroDaSerieDaNotaFiscalDaDuplicata;
  private final CnabKey<PaulistaLoteRemessa, Cep> cep;
  private final CnabKey<PaulistaLoteRemessa, String> cedente;
  private final CnabKey<PaulistaLoteRemessa, Integer> seqRegistro;

  PaulistaLoteRemessaSpec() {
    idDoRegistro = id("Identificação do registro")

        .at(1, 1).colunaFixa("1").toKey();

    debitoAutomaticoCC = id("Débito Automático C/C")

        .at(2, 20).colunaFixa("").opcional().toKey();

    coObrigacao = id("Coobrigação 01 Com Coobrigação, 02 Sem Coobrigação")

        .at(21, 22).colunaInteger().opcional().toKey();        

    caracteristicaEspecial = id("Característica Especial")

        .at(23, 24).colunaInteger().opcional().toKey();
    
    modalidadeDaOperacao = id("Modalidade da Operação")
        .at(25, 28).colunaInteger().opcional().toKey();
    
    naturezaDaOperacao = id("Natureza da Operação")
        .at(29, 30).colunaInteger().opcional().toKey();
    
    origemDoRecurso = id("Origem do Recurso")
        .at(31, 34).colunaInteger().opcional().toKey();
    
    classeRiscoDaOperacao = id("Classe Risco da Operação")
        .at(35, 36).colunaAlfanumerica().opcional().toKey();
    
    zeros = id("Zeros")
        .at(37, 37).colunaFixa("0").opcional().toKey();

    numeroDeControleDoParticipante = id("Numero de identificação do titulo na Consultoria")
        .at(38, 62).colunaAlfanumerica().toKey();
    
    numeroDoBanco = id("Numero do Banco")
        .at(63, 65).colunaInteger().toKey();
    
    zeros2 = id("Zeros")
        .at(66, 70).colunaFixa("00000").toKey();
    
    idTituloNoBanco = id("Identificação do Título do Banco")
        .at(71, 78).colunaBranco().opcional().toKey();
    
    nossoNumero = id("Dígito do nosso número")
        .at(82, 82).colunaAlfanumerica().opcional().toKey();
    
    valorPago = id("Valor pago na liquidação/baixa do titulo")
        .at(83, 92).colunaValorFinanceiro().opcional().toKey();
    
    condicaoParaEmissaoDaPapeletaDeCobranca = id("Condição para Emissão de Papeleta de Cobrança")
        .at(93, 93).colunaBranco().opcional().toKey();
    
    idSeEmitePapeletaParaDebitoAutomatico = id("Identificação se emite papeleta para Débito Automático")
        .at(94, 94).colunaBranco().opcional().toKey();
    
    dataDeLiquidacao = id("Data de Liquidação")
        .at(95, 100).colunaLocalDate().toKey();
    
    idOperacaoDoBanco = id("Identificação da Operação do Banco")
        .at(101, 104).colunaBranco().opcional().toKey();
    
    indicadorRateioCredito = id("Indicador Rateio Crédito")
        .at(105, 105).colunaBranco().opcional().toKey();
    
    enderecamentoParaAvisoDoDebitoAutomaticoEmCC = id("Endereçamento para Aviso do Débito Automático em Conta Corrente")
        .at(106, 106).colunaBranco().opcional().toKey();
    
    branco = id("Branco")
        .at(107, 108).colunaBranco().opcional().toKey();
    
    idOcorrencia = id("Identificação Ocorrencia")
        .at(109, 110).colunaInteger().toKey();
    
    numeroDoDocumento = id("Número do Documento")
        .at(111, 120).colunaAlfanumerica().toKey();
    
    dataDeVencimentoDoTitulo = id("Data de Vencimento do Titulo")
        .at(121, 126).colunaLocalDate().toKey();
    
    valorFaceDoTitulo = id("Valor do título")
        .at(127, 139).colunaValorFinanceiro().toKey();
    
    bancoEncarregadoDaCobranca = id("Número do Banco na Câmara de compensação ou 000")
        .at(140, 142).colunaInteger().opcional().toKey();
    
    agenciaDepositaria = id("Código da Agência Depositaria ou 00000")
        .at(143, 147).colunaAlfanumerica().opcional().toKey();
    
    especieDeTitulo = id("Espécie de título 01 Duplicata, 02 Nota Promissória, 51 Cheque, 60 Contratos")
        .at(148, 149).colunaInteger().toKey();
    
    identificacao = id("Branco")
        .at(150, 150).colunaBranco().opcional().toKey();
    
    dataDeEmissaoDoTitulo = id("Data de Emissão do Título")
        .at(151, 156).colunaLocalDate().toKey();
    
    primeiraInstrucao = id("Primeira instrução 00")
        .at(157, 158).colunaFixa("00").toKey();
    
    segundaInstrucao = id("Segunda instrução 0")
        .at(159, 159).colunaFixa("0").toKey();
    
    zeros3 = id("Zeros")
        .at(160, 173).colunaFixa("00000000000000").opcional().toKey();
    
    numeroDeTermoDeCessao = id("Número do Termo de Cessão")
        .at(174, 192).colunaAlfanumerica().opcional().toKey();
    
    valorPresenteDaParcela = id("Valor da Parcela na Data que foi Cedida")
        .at(193, 205).colunaValorFinanceiro().toKey();
    
    valorDoAbatimento = id("Valor da Parcela na Data que foi Cedida")
        .at(206, 218).colunaValorFinanceiro().opcional().toKey();
    
    identificacaoDoTipoDeInscricaoDoSacado = id("Identificação do Tipo de Inscrição do Sacado 01 CPF, 02 CNPJ")
        .at(219, 220).colunaEnum(TipoDeIncricaoDoSacado.class).toKey();
    
    numeroInscricaoDoSacado = id("Número de Inscrição do sacado")
        .at(221, 234).colunaCadastroDaEmpresa().toKey();
    
    nomeDoSacado = id("Nome do Sacado")
        .at(235, 274).colunaAlfanumerica().toKey();
    
    enderecoCompletoDoSacado = id("Endereço Completo do Sacado")
        .at(275, 314).colunaAlfanumerica().toKey();
    
    numeroDeNotaFiscalDaDuplicata = id("Número de Nota Fiscal da Duplicata")
        .at(315, 323).colunaAlfanumerica().opcional().toKey();

    numeroDaSerieDaNotaFiscalDaDuplicata = id("Número da Série da Nota Fiscal da Duplicata")
        .at(324, 326).colunaAlfanumerica().opcional().toKey();
    
    cep = id("Código de Endereço Postal")
        .at(327, 334).colunaCep().toKey();

    cedente = id("Cedente")
        .at(335, 394).colunaAlfanumerica().toKey();
    
    seqRegistro = id("Número de Sequencia do Registro")
        .at(395, 400).colunaInteger().toKey();
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> idDoRegistro() {
    return idDoRegistro;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa,String> debitoAutomaticoCC() {
    return debitoAutomaticoCC;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa,Integer> coObrigacao() {
    return coObrigacao;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, Integer> caracteristicaEspecial() {
    return caracteristicaEspecial;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, Integer> modalidadeDaOperacao() {
    return modalidadeDaOperacao;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, Integer> naturezaDaOperacao() {
    return naturezaDaOperacao;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, Integer> origemDoRecurso() {
    return origemDoRecurso;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> classeRiscoDaOperacao() {
    return classeRiscoDaOperacao;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> zeros() {
    return zeros;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> numeroDeControleDoParticipante() {
    return numeroDeControleDoParticipante;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, Integer> numeroDoBanco() {
    return numeroDoBanco;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> zeros2() {
    return zeros2;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa,String> idTituloNoBanco() {
    return idTituloNoBanco;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa,String> nossoNumero() {
    return nossoNumero;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, Double> valorPago() {
    return valorPago;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> condicaoParaEmissaoDaPapeletaDeCobranca() {
    return condicaoParaEmissaoDaPapeletaDeCobranca;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> idSeEmitePapeletaParaDebitoAutomatico() {
    return idSeEmitePapeletaParaDebitoAutomatico;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, LocalDate> dataDeLiquidacao() {
    return dataDeLiquidacao;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> idOperacaoDoBanco() {
    return idOperacaoDoBanco;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> indicadorRateioCredito() {
    return indicadorRateioCredito;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa,String> enderecamentoParaAvisoDoDebitoAutomaticoEmCC() {
    return enderecamentoParaAvisoDoDebitoAutomaticoEmCC;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> branco() {
    return branco;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, Integer> idOcorrencia() {
    return idOcorrencia;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> numeroDoDocumento() {
    return numeroDoDocumento;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, LocalDate> dataDeVencimentoDoTitulo() {
    return dataDeVencimentoDoTitulo;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa,Double> valorFaceDoTitulo() {
    return valorFaceDoTitulo;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, Integer> bancoEncarregadoDaCobranca() {
    return bancoEncarregadoDaCobranca;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> agenciaDepositaria() {
    return agenciaDepositaria;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, Integer> especieDeTitulo() {
    return especieDeTitulo;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> identificacao() {
    return identificacao;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, LocalDate> dataDeEmissaoDoTitulo() {
    return dataDeEmissaoDoTitulo;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> primeiraInstrucao() {
    return primeiraInstrucao;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> segundaInstrucao() {
    return segundaInstrucao;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> zeros3() {
    return zeros3;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> numeroDeTermoDeCessao() {
    return numeroDeTermoDeCessao;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, Double> valorPresenteDaParcela() {
    return valorPresenteDaParcela;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, Double> valorDoAbatimento() {
    return valorDoAbatimento;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, TipoDeIncricaoDoSacado> identificacaoDoTipoDeInscricaoDoSacado() {
    return identificacaoDoTipoDeInscricaoDoSacado;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, CadastroRFB> numeroInscricaoDoSacado() {
    return numeroInscricaoDoSacado;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> nomeDoSacado() {
    return nomeDoSacado;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> enderecoCompletoDoSacado() {
    return enderecoCompletoDoSacado;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> numeroDeNotaFiscalDaDuplicata() {
    return numeroDeNotaFiscalDaDuplicata;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> numeroDaSerieDaNotaFiscalDaDuplicata() {
    return numeroDaSerieDaNotaFiscalDaDuplicata;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, Cep> cep() {
    return cep;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, String> cedente() {
    return cedente;
  }

  @Override
  public CnabKey<PaulistaLoteRemessa, Integer> seqRegistro() {
    return seqRegistro;
  }

  @Override
  Class<PaulistaLoteRemessa> getBancoKeyClass() {
    return getBancoKeyClass();
  }
  
}